/**
 * 
 */
package com.hollycrm.hollysqm.handle.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.hollycrm.hollysqm.bean.PlanMethodBean;
import com.hollycrm.hollysqm.entities.TblQmPaper;
import com.hollycrm.hollysqm.entities.TblQmPaperLog;
import com.hollycrm.hollysqm.entities.TblQmPlan;
import com.hollycrm.hollysqm.entities.TblQmPlanExtract;
import com.hollycrm.hollysqm.entities.TblQmPlanParam;
import com.hollycrm.hollysqm.entities.TblQmPlanUser;
import com.hollycrm.hollysqm.entities.TblQmQualityUser;
import com.hollycrm.hollysqm.entities.TblSnsSessionQuery;
import com.hollycrm.hollysqm.entities.TblVocCustcontinfo;
import com.hollycrm.hollysqm.handle.dao.CustcontinfoDao;
import com.hollycrm.hollysqm.handle.dao.QmPaperDao;
import com.hollycrm.hollysqm.handle.dao.QmPaperLogDao;
import com.hollycrm.hollysqm.handle.dao.SnsSessionQueryDao;
import com.hollycrm.hollysqm.util.Constant;
import com.hollycrm.hollysqm.util.UuidUtil;

/**
 * 分配质检单，分配策略（0平均、1随机，默认为0）
 * @author jianglong
 * @date 2017年3月31日 下午2:53:23
 */
@Scope("prototype")
@Service
public class AllotMethodService extends MethodService{

	private static final Logger log = LoggerFactory.getLogger(AllotMethodService.class);
	
	@Autowired
    private JdbcTemplate jdbc;
	@Autowired
	private CustcontinfoDao custcontinfoDao;
	@Autowired
	private SnsSessionQueryDao snsSessionQueryDao;
	@Autowired
	private QmPaperDao qmPaperDao;
	@Autowired
	private QmPaperLogDao qmPaperLogDao;
	
	/**
	 * 分配质检单：按策略分配质检单给每一个质检员
	 * @param paln
	 * @param planParam
	 * @param paramMap
	 */
	public int excuteAllot(TblQmPlan plan ,TblQmPlanParam planParam, Map<String, Object> paramMap, String dataType) throws Exception {
		String allotMethod = (String) paramMap.get("allotMethod");
		boolean strategy = StringUtils.equals(allotMethod, "1") ? false : true; //分配策略（0平均、1随机，默认为0）
		//读取接触记录数据
		List<PlanMethodBean> infoList = null;
		if(dataType.equals(Constant.V8)) {
			List<TblVocCustcontinfo> v8infoList = custcontinfoDao.getCustcontinfoList(plan.getPlanId());
			infoList = parseV8Record(v8infoList);
		} else if(dataType.equals(Constant.I8)) {
			List<TblSnsSessionQuery>  i8infoList = snsSessionQueryDao.getTblSnssession(plan.getPlanId());
			infoList = parseI8Record(i8infoList);
		}
		
		if (CollectionUtils.isEmpty(infoList))
			return 0;
		List<TblQmQualityUser> qualityUserList = this.getQualityUserList(plan.getPlanId());
		Map<String,String> userMap = getPlanUserMap(plan.getPlanId());
		Map<String,String> agetnMap = getPlanExtractAgentCodeMap(plan.getPlanId());
		Random r = new Random();
		TblQmPaper paper = null;
		TblQmPaperLog paperLog = null;
		int i = -1, c =0, count = 0;
		String sysAgentCode = null;
		String sysUserCode = null;
		int size = qualityUserList.size();	
		List<TblQmPaper> paperList = new ArrayList<>();
		List<TblQmPaperLog> paperLogList = new ArrayList<>();
		for (PlanMethodBean info : infoList){
			sysAgentCode = agetnMap.get(info.getId());//测试专用
			sysUserCode = userMap.get(sysAgentCode);//测试专用，正式后，这块需要改成 info.getUserCode()
			if (StringUtils.isBlank(sysUserCode)){//如果该userCode在userMap中不存在，则表示该条记录非抽取坐席
				continue;
			}
			//分配策略
			if (strategy){				
				i++;
				//平均分配（顺序分配）每一个质检员
				i  = i >= size ? 0 : i;
			}else{
				i = r.nextInt(size);//随机分配（任意选择）一个质检员
			}
			//封装质检单,需要说明：坐席工号在Solr中和接触记录中以userCode字段存储，但在框架中是以user_no字段存储，因此info.getUserCode()指的是user_no【坐席工号】
			paper = this.createPaper(plan, info.getId(), sysAgentCode, sysUserCode , qualityUserList.get(i), c++);
			paperList.add(paper);
			paperLog = this.createPaperLog(paper);
			paperLogList.add(paperLog);
			//每50个提交一次
			if (c % 50 == 0){
				this.batSavePaper(paperList);
				paperList.clear();
				this.batSavePaperLog(paperLogList);
				paperLogList.clear();
			}
			count ++ ;
		}
		//有未提交的质检单
		if (paperList.size()>0){
			this.batSavePaper(paperList);
			this.batSavePaperLog(paperLogList);
		}
		infoList = null;
		paperLogList = null;
		return count;
	}
	
	/**
	 * 抽取计划》保存质检单
	 * @param paln
	 * @param paperDetailId
	 * @param agentCode
	 * @param qualityUser
	 * @param paperNo
	 */
	private TblQmPaper createPaper(TblQmPlan plan ,String paperDetailId,String agentCode,String userCode,TblQmQualityUser qualityUser,int paperNo){
		TblQmPaper paper = new TblQmPaper();
		paper.setPaperId(UuidUtil.getUuid());//质检单编号
		paper.setPlanId(plan.getPlanId());//抽取计划表ID(TBL_QM_PLAN.PLAN_ID)
		paper.setPaperDetailId(paperDetailId);//接触记录表ID(TBL_VOC_CUSTCONTINFO.CUSTCONTINFO_ID)
		paper.setStandardId(plan.getStandardId());//评价标准表ID(TBL_QM_STANDARD.STANDARD_ID)	
		paper.setPaperType(plan.getDataType());//质检单类型：V8：录音质检，I8：文本质检
		paper.setQualityStatus("0");//质检状态（0：未质检，1：已质检，2已申诉，3已通过，4已驳回）
		paper.setUserCode(userCode);//坐席账号
		paper.setAgentCode(agentCode);//坐席工号
		paper.setCheckerAgentCode(qualityUser.getAgentCode());//质检员工号
		paper.setCheckerCode(qualityUser.getUserCode());//质检员账号（来自人员信息扩展的账号）
		paper.setAmount(0);//评价标准总分
		paper.setComments(null);//评语（问题描述）
		paper.setCreateTime(DateFormatUtils.format(new Date(), Constant.YYYY_MM_DD_HH_MM_SS));//质检单创建时间
		paper.setStartTime(null);//质检开始时间
		paper.setEndTime(null);//质检结束时间
		paper.setIsPublicResult("0");//是否发布成绩（0否，1是）
		paper.setPaperNo(paperNo);//质检单序号
		paper.setReleaseTime(null);//成绩发布时间
		paper.setReviewScore(0);//复核总得分(有申诉复核，才有该分数)
		paper.setTotalScore(0);//实际总得分
		paper.setAreaId(plan.getAreaId());//地域ID
		paper.setDomainId(plan.getDomainId());//租户ID
		paper.setModifier(paper.getCheckerCode());
		paper.setModifyTime(paper.getCreateTime());
		return paper ;
	}
	
	/**
	 * 创建质检状态历史记录信息,该表需要记录每次状态变更信息
	 * @param paper
	 * @return
	 */
	private TblQmPaperLog createPaperLog(TblQmPaper paper){
		TblQmPaperLog paperLog = new TblQmPaperLog();
		paperLog.setPaperLogId(UuidUtil.getUuid());
		paperLog.setPaperId(paper.getPaperId());		
		paperLog.setModifier(paper.getCheckerCode());//哪个质检员进行待评分
		paperLog.setModifyTime(paper.getCreateTime());		
		paperLog.setQualityStatus(paper.getQualityStatus());//质检状态（0：未质检，1：已质检，2已申诉，3已通过，4已驳回）
		return paperLog;
	}
	
	/**
	 * 批量保存质检单
	 * @param paperList
	 */
	private void batSavePaper(List<TblQmPaper> paperList){
		try{
			qmPaperDao.save(paperList);
		} catch(Exception e){
			log.info("抽取计划》保存质检单异常...",e);
		}
	}
	
	/**
	 * 批量保存质检单历史
	 * @param paperList
	 */
	private void batSavePaperLog(List<TblQmPaperLog> paperLogList){
		try{
			qmPaperLogDao.save(paperLogList);
		} catch(Exception e){
			log.info("抽取计划》保存质检单异常...",e);
		}
	}
	
	/**
	 * 获取质检计划被质检坐席
	 * @param planId
	 * @return
	 */
	public List<TblQmQualityUser> getQualityUserList(final String planId) throws Exception {
		//sql,参数,返回的类型
		return (List<TblQmQualityUser>)jdbc.query("select plan_id as planId,user_code as userCode,agent_code as agentCode from tbl_qm_quality_user where plan_id=?", 
				new Object[]{planId}, new BeanPropertyRowMapper<TblQmQualityUser>(TblQmQualityUser.class));
	}
	
	/**
	 * 获取指定时间段上的接触记录用户信息
	 * @param startTime
	 * @param endTime
	 * @return
	 * @throws Exception
	 */
	public Map<String,String> getPlanUserMap(String planId) throws Exception {		
		Map<String,String> userMap = new HashMap<String,String>();
		try{
			//sql,参数,返回的类型
			List<TblQmPlanUser> userList = (List<TblQmPlanUser>) jdbc.query("select plan_id as planId,user_code as userCode,agent_code as agentCode from tbl_qm_plan_user where plan_id=?", 
					new Object[]{planId}, new BeanPropertyRowMapper<TblQmPlanUser>(TblQmPlanUser.class));
			if (userList!=null){
				for (TblQmPlanUser user : userList){
					userMap.put(user.getAgentCode(), user.getUserCode());
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return userMap;
	}
	
	/**
	 * 获取指定时间段上的接触记录工号信息【测试专用】
	 * @param startTime
	 * @param endTime
	 * @return
	 * @throws Exception
	 */
	public Map<String,String> getPlanExtractAgentCodeMap(String planId) throws Exception {		
		Map<String,String> userMap = new HashMap<String,String>();
		try{
			//sql,参数,返回的类型
			List<TblQmPlanExtract> userList = (List<TblQmPlanExtract>) jdbc.query("select data_id as dataId ,agent_code as agentCode from tbl_qm_plan_extract where plan_id=?", 
					new Object[]{planId}, new BeanPropertyRowMapper<TblQmPlanExtract>(TblQmPlanExtract.class));
			if (userList!=null){
				for (TblQmPlanExtract extract : userList){
					userMap.put(extract.getDataId(), extract.getAgentCode());
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return userMap;
	}
	
	
	
}
